package sc.prototype.pfs.eventnotify.filter.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import sc.common.test.VelocityUtil;
import sc.prototype.pfs.eventnotify.filter.NotifyConfigFilter;
import sc.prototype.pfs.eventnotify.model.NotifyEvent;
import sc.prototype.pfs.eventnotify.model.NotifyConfig;

/**
 * 事件订阅配置筛选器
 */
public class DefaultNotifyConfigFilter implements NotifyConfigFilter {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public List<NotifyConfig> filter(NotifyEvent event, List<NotifyConfig> configs) {
        ArrayList<NotifyConfig> remains = new ArrayList<NotifyConfig>();
        if (CollectionUtils.isEmpty(configs)) {
            return remains;
        }
        for (NotifyConfig cfg : configs) {
            if (isConfigNotValid(cfg)) {
                //配置未生效或过期
                continue;
            }
            if (cfg.getEventType() != event.getEventType()) {
                //事件类型不匹配
                continue;
            }
            if (StringUtils.isBlank(cfg.getMatchExpression())) {
                //表达式为空默认为匹配
                remains.add(cfg.clone());
            } else if (getMatchResult(event, cfg)) {
                //表达式不为空，运算表达式
                remains.add(cfg.clone());
            }
        }
        return remains;
    }

    /** 运算匹配表达式，可以使用变量包括，配置：config，事件：event */
    public boolean getMatchResult(NotifyEvent event, NotifyConfig config) {
        HashMap<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("config", config);
        paramMap.put("event", event);
        String rst = VelocityUtil.getString(config.getMatchExpression(), paramMap);
        rst = StringUtils.trim(rst);
        return StringUtils.contains(rst, NotifyConfig.MATCH_CONTAIN);
    }

    /** 判断配置是否有效 */
    public boolean isConfigNotValid(NotifyConfig config) {
        Date now = DateTime.now().toDate();
        return config.getGmtBeginValid().after(now) || config.getGmtBeginInvalid().before(now);
    }

}
